#pragma once

#include <MyFC/Event.h>
#include "Types.h"
#include "DLL.h"
#include "Doc.h"

#if defined(OpenEvent)
#undef OpenEvent
#endif

namespace My {

/**
 * Class describing a frame sequence
 */
class Sequence : public virtual EventDispatcher
{
public:
/// Status
	virtual bool IsEmpty() const = 0;
/// Returns number of the start frame
	virtual int GetStart() const = 0;
/// Returns number of frames in this sequence
	virtual Size GetDuration() const = 0;
/// Returns the work area
	virtual Span GetWorkArea() const = 0;
/// Sets the work area
	virtual void SetWorkArea(Span) = 0;
/// Returns the current frame
	virtual int GetCurrentFrame() const = 0;
/// Sets the current frame
	virtual void SetCurrentFrame(int) = 0;
/// Returns the preview frame
	virtual int GetPreviewFrame() const = 0;
/// Sets the preview frame
	virtual void SetPreviewFrame(int) = 0;
/// Returns dimension of images in this sequence
	virtual Extent GetDim() const 
		{ return Extent(0, 0); }
/// Returns true if Player may swap to Follow mode (typically it's so during processing)
	virtual bool CanStartFollow() const
		{ return false; }
// Helper methods:
public:
	Span GetTimeSpan() const; ///< returns [GetStart(), GetStart() + GetDuration())
// Events:
public:
	class Event : public My::Event {
	public:
		Sequence & m_Sequence;
	public:
		Event(Sequence & s) : m_Sequence(s) { }
	};
	class OpenEvent : public Event { 
	public:
		OpenEvent(Sequence & s) : Event(s) { }
	};
	class CloseEvent : public Event { 
	public:
		CloseEvent(Sequence & s) : Event(s) { }
	};
	class StartChange : public Event { 
	public:
		StartChange(Sequence & s) : Event(s) { }
	};
	class DurationChange : public Event { 
	public:
		DurationChange(Sequence & s) : Event(s) { }
	};
	class WorkAreaChange : public Event { 
	public:
		WorkAreaChange(Sequence & s) : Event(s) { }
	};
	class CurrentFrameChange : public Event { 
	public:
		CurrentFrameChange(Sequence & s) : Event(s) { }
	};
	class PreviewFrameChange : public Event { 
	public:
		PreviewFrameChange(Sequence & s) : Event(s) { }
	};
};

} // My

#include "impl/Sequence.inl"
